package com.wchen.project.zk.curator;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.NodeCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;

/**
 * @Desc:   使用 Curator 的 NodeCache 监听指定 Zookeeper 数据节点本身的变化
 *
 *          NodeCache 不仅可以用于监听数据节点的内容变更，也能监听指定节点是否
 *          存在，如果原本节点不存在，那么 Cache 就会在节点被创建后出发 NodeCacheListener。
 *          但是如果该数据节点被删除，那么 Curator 就无法触发 NodeCacheListener 了。
 * @author: cww
 * @DateTime: 2020-01-24 16:05
 */

public class ZkNodeListenerByNodeCache {
    static String path = "/zk-book/nodecache";
    static CuratorFramework client = CuratorFrameworkFactory.builder()
            .connectString("home:2181")
            .sessionTimeoutMs(5000)
            .retryPolicy(new ExponentialBackoffRetry(1000,3))
            .build();

    public static void main(String[] args) throws Exception{
        client.start();
        client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath(path, "init".getBytes());
        // boolean dataIsCompressed 如果为 true 那么 NodeCache 会在第一次启动时就立刻从 Zookeeper 上读取对应节点的
        // 数据内容，并保存在 Cache 中
        final NodeCache cache = new NodeCache(client, path, false);
        cache.start(true);
        cache.getListenable().addListener(new NodeCacheListener() {
            @Override
            public void nodeChanged() throws Exception {
                System.out.println("Node data update, new data: " + new String(cache.getCurrentData().getData()));
            }
        });
        client.setData().forPath(path, "u".getBytes());
        Thread.sleep(1000);
        client.delete().deletingChildrenIfNeeded().forPath(path);
        Thread.sleep(5000);
    }
}
